package com.yunpeng.aidevice.biz.service.impl;

import com.yunpeng.aidevice.biz.service.IFunctionNodeBizService;
import com.yunpeng.common.dto.Result;
import com.yunpeng.aidevice.common.vo.FunctionNodeDetailVO;
import com.yunpeng.aidevice.common.vo.FunctionNodePermissionVO;
import com.yunpeng.aidevice.common.vo.FunctionPermissionVO;
import com.yunpeng.aidevice.dao.service.IFunctionNodeService;
import com.yunpeng.aidevice.common.enums.ResultCodeEnum;
import com.yunpeng.aidevice.dao.model.entity.FunctionNodeDO;
import com.yunpeng.aidevice.dao.model.relation.FunctionsNodeRelationPermissionsDO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * FunctionNodeBizServiceImpl
 *
 * @author : Moore(hemw)
 * @date : 2020-04-15
 */
@Service
public class FunctionNodeBizServiceImpl implements IFunctionNodeBizService {

    /**
     * 日志对象
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(FunctionNodeBizServiceImpl.class);

    @Resource
    private IFunctionNodeService functionNodeService;

    @Override
    /**
     * 新增功能节点
     *
     * @param name         功能名称
     * @param url          路径url
     * @param folder       是否文件夹
     * @param parentCode   父节点代码
     * @param operatorCode 操作人代码
     * @return
     */
    public Result<Void> addNew(String name, String url, Boolean folder, String parentCode, String operatorCode) {
        if (functionNodeService.addNew(name, url, folder, parentCode, operatorCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 删除功能节点
     *
     * @param functionNodeCode 功能节点代码
     * @return
     */
    public Result<Void> remove(String functionNodeCode) {
        if (functionNodeService.remove(functionNodeCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.REMOVE_FAILED);
    }


    @Override
    /**
     * 功能节点绑定权限
     *
     * @param nodeCode        功能节点代码
     * @param permissionCodes 权限代码集合
     * @param operatorCode    操作人代码
     * @return
     */
    public Result<Void> bindPermission(String nodeCode, List<String> permissionCodes, String operatorCode) {
        if (functionNodeService.bindPermission(nodeCode, permissionCodes, operatorCode)) {
            return Result.success();
        }
        return Result.fail(ResultCodeEnum.SAVE_DATA_FAILED);
    }

    @Override
    /**
     * 获取功能节点详情数据
     *
     * @param nodeCode 功能节点代码
     * @return
     */
    public Result<FunctionNodeDetailVO> detailInfo(String nodeCode) {
        FunctionNodeDO functionNodeDO = functionNodeService.getByCode(nodeCode);
        if (functionNodeDO == null || functionNodeDO.getId() == null) {
            return Result.fail(ResultCodeEnum.NOT_EXISTS_DATA_FAILED);
        }
        List<FunctionsNodeRelationPermissionsDO> functionsNodeRelationPermissionsDOList = functionNodeService.queryRelationListByNodeCode(nodeCode);
        FunctionNodeDetailVO functionNodeDetailVO = new FunctionNodeDetailVO();
        functionNodeDetailVO.setName(functionNodeDO.getName());
        functionNodeDetailVO.setCode(functionNodeDO.getCode());
        functionNodeDetailVO.setUrl(functionNodeDO.getUrl());
        functionNodeDetailVO.setFolder(functionNodeDO.getFolder());
        functionNodeDetailVO.setParentName(functionNodeDO.getParentName());
        functionNodeDetailVO.setParentCode(functionNodeDO.getParentCode());
        if (functionsNodeRelationPermissionsDOList != null && functionsNodeRelationPermissionsDOList.size() > 0) {
            functionNodeDetailVO.setOperatePermissions(functionsNodeRelationPermissionsDOList.stream().map(t -> new FunctionNodePermissionVO(t.getFunctionNodeCode(), t.getFunctionNodeName(), t.getPermissionCode(), t.getPermissionName())).collect(Collectors.toList()));
        }
        return Result.success(functionNodeDetailVO);
    }

    @Override
    /**
     * 返回树状的功能节点列表
     *
     * @return
     */
    public Result<List<FunctionPermissionVO>> treeList() {
        List<FunctionNodeDO> functionNodeDOList = functionNodeService.queryAllList();
        if (functionNodeDOList == null || functionNodeDOList.isEmpty()) {
            return Result.success(new ArrayList<>());
        }
        //摘出顶级节点
        List<FunctionNodeDO> rootNodeList = new ArrayList<>();
        List<FunctionNodeDO> anotherNodeList = new ArrayList<>();
        for (FunctionNodeDO functionNodeDO : functionNodeDOList) {
            if (functionNodeDO.getParentCode() == null) {
                rootNodeList.add(functionNodeDO);
            } else {
                anotherNodeList.add(functionNodeDO);
            }
        }
        //顶级节点循环组装树
        List<FunctionPermissionVO> result = new ArrayList<>();
        for (FunctionNodeDO functionNodeDO : rootNodeList) {
            FunctionPermissionVO functionPermissionVO = new FunctionPermissionVO();
            functionPermissionVO.setNodeLocation(functionNodeDO.getUrl());
            functionPermissionVO.setNodeName(functionNodeDO.getName());
            functionPermissionVO.setFolder(functionNodeDO.getFolder());
            functionPermissionVO.setNodeCode(functionNodeDO.getCode());
            functionPermissionVO.setChildNodes(recursiveGetTree(functionNodeDO, anotherNodeList));
            result.add(functionPermissionVO);
        }
        return Result.success(result);
    }

    //region 私有方法

    /**
     * 递归组装功能权限树
     *
     * @param parentNode 父级节点
     * @param list
     * @return
     */
    private List<FunctionPermissionVO> recursiveGetTree(FunctionNodeDO parentNode, List<FunctionNodeDO> list) {
        //获取子集节点和其他节点
        List<FunctionNodeDO> currentSubList = new ArrayList<>();
        List<FunctionNodeDO> removeSubList = new ArrayList<>();
        for (FunctionNodeDO functionNodeDO : list) {
            if (parentNode.getCode().equalsIgnoreCase(functionNodeDO.getParentCode())) {
                currentSubList.add(functionNodeDO);
            } else {
                removeSubList.add(functionNodeDO);
            }
        }
        List<FunctionPermissionVO> result = new ArrayList<>();
        for (FunctionNodeDO functionNodeDO : currentSubList) {
            FunctionPermissionVO functionPermissionVO = new FunctionPermissionVO();
            functionPermissionVO.setNodeLocation(functionNodeDO.getUrl());
            functionPermissionVO.setNodeName(functionNodeDO.getName());
            functionPermissionVO.setNodeCode(functionNodeDO.getCode());
            functionPermissionVO.setFolder(functionNodeDO.getFolder());
            functionPermissionVO.setChildNodes(recursiveGetTree(functionNodeDO, removeSubList));
            if (functionPermissionVO.getChildNodes().isEmpty() && functionNodeDO.getFolder()) {
                continue;
            }
            result.add(functionPermissionVO);
        }
        return result;
    }

    //endregion
}
